\subsection{Простой пример}

\lstinputlisting[style=customc]{patterns/04_scanf/1_simple/ex1.c}

Использовать \scanf в наши времена для того, чтобы спросить у пользователя что-то --- не самая хорошая идея.
Но так мы проиллюстрируем передачу указателя на переменную типа \Tint.

\subsubsection{Об указателях}
\myindex{\CLanguageElements!\Pointers}

Это одна из фундаментальных вещей в программировании.
Часто большой массив, структуру или объект передавать в другую функцию путем копирования данных невыгодно, а передать адрес массива, структуры или объекта куда проще.
Например, если вы собираетесь вывести в консоль текстовую строку, достаточно только передать её адрес в ядро \ac{OS}.

К тому же, если вызываемая функция (\gls{callee}) должна изменить что-то в этом большом массиве или структуре, то возвращать её полностью так же абсурдно.
Так что самое простое, что можно сделать, это передать в функцию-\gls{callee} адрес массива или структуры, и пусть \gls{callee} что-то там изменит.

Указатель в \CCpp --- это просто адрес какого-либо места в памяти.

\myindex{x86-64}
В x86 адрес представляется в виде 32-битного числа (т.е. занимает 4 байта), а в x86-64 как 64-битное число (занимает 8 байт).
Кстати, отсюда негодование некоторых людей, связанное с переходом на x86-64 --- на этой архитектуре все указатели занимают в 2 раза больше места, в том числе и в ``дорогой'' кэш-памяти.

% TODO ... а делать разные версии memcpy для разных типов - абсурд
\myindex{\CStandardLibrary!memcpy()}
При некотором упорстве можно работать только с безтиповыми указателями (\TT{void*}), например, стандартная функция Си \TT{memcpy()},
копирующая блок из одного места памяти в другое принимает на вход 2 указателя типа \TT{void*}, потому что нельзя заранее предугадать, какого типа блок вы собираетесь копировать.
Для копирования тип данных не важен, важен только размер блока.

Также указатели широко используются, когда функции нужно вернуть более одного значения
(мы ещё вернемся к этому в будущем
~(\myref{label_pointers})
).

Функция \IT{scanf()}---это как раз такой случай.

Помимо того, что этой функции нужно показать, сколько значений было прочитано успешно, ей ещё и нужно вернуть сами значения.

Тип указателя в \CCpp нужен только для проверки типов на стадии компиляции.

Внутри, в скомпилированном коде, никакой информации о типах указателей нет вообще.
% TODO это сильно затрудняет декомпиляцию

\input{patterns/04_scanf/1_simple/x86}
\input{patterns/04_scanf/1_simple/x64}
\input{patterns/04_scanf/1_simple/ARM}
\input{patterns/04_scanf/1_simple/MIPS/main}
